package com.sdlight.snowflake.service;

import com.sankuai.inf.leaf.IDGen;
import com.sankuai.inf.leaf.common.Result;
import com.sankuai.inf.leaf.snowflake.SnowflakeIDGenImpl;

import com.sdlight.snowflake.conf.AppConfig;
import com.sdlight.snowflake.exception.InitException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;

/**
 * snowflake模式的service层
 *
 * @author lihaitao
 */
@Service
@Slf4j
public class SnowflakeService implements ApplicationListener<WebServerInitializedEvent> {

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private InetUtils inetUtils;

    /**
     * ID生成器
     */
    IDGen idGen;

    /**
     * 监听WebServerInitializedEvent事件.
     * <p>在WebServer初始化完成后，才能成功获取到端口。然后进行初始化</p>
     *
     * @param event
     */
    @Override
    public void onApplicationEvent(WebServerInitializedEvent event) {
        idGenInit(event);
    }

    /**
     * 初始化id生成器.
     *
     * @param event
     */
    private void idGenInit(WebServerInitializedEvent event) {
        try {
            String zkConnStr = appConfig.getZkConnStr();
            // 获取当前应用的ip
            String ip = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
            int port = event.getWebServer().getPort();
            idGen = new SnowflakeIDGenImpl(zkConnStr, ip, port);
            // 2. 初始化ID生成器
            if (idGen.init()) {
                log.info("Snowflake Service Init Successfully");
            } else {
                throw new InitException("Snowflake Service Init Fail");
            }
        } catch (Exception e) {
            log.error("Snowflake Service Init Fail", e);
        }
    }

    /**
     * 通过ID生成器获得key对应的id
     *
     * @param key
     * @return
     */
    public Result getId(String key) {
        return idGen.get(key);
    }
}
